package com.gjy.util.sb.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.gjy.util.sb.aop.dto.DataPermission;
import com.google.common.collect.Lists;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import javax.annotation.Resource;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.List;

/**
 * @author 宫静雨
 * @version 1.0
 * @since 2023-10-26 15:52:44
 */
@RequestMapping("/export")
@RestController
public class ExportController {

    private static final Logger log = LoggerFactory.getLogger(ExportController.class);

    @Resource
    private ObjectMapper objectMapper;

    @GetMapping("/json")
    public ResponseEntity<StreamingResponseBody> exportJson() {

        List<DataPermission> list = Lists.newArrayList(
                DataPermission.builder().userId("1").a("a").b("b").all(true).build(),
                DataPermission.builder().userId("2").a("c").b("c").all(false).build(),
                DataPermission.builder().userId("3").a("d").b("d").all(false).build()
        );

        StreamingResponseBody responseBody = os -> {
            try (Writer writer = new BufferedWriter(new OutputStreamWriter(os))) {
                objectMapper.writeValue(writer, list);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        };

        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=data.json");
        headers.add(HttpHeaders.CONTENT_TYPE, "application/json");
        return new ResponseEntity<>(responseBody, headers, HttpStatus.OK);
    }

    @GetMapping("/json2")
    public ResponseEntity<StreamingResponseBody> exportJson2() {
        String a = "D:\\code\\java\\microservice_spc\\util-service\\src\\main\\resources\\application.yml";

        StreamingResponseBody responseBody = os -> {
            try (FileInputStream is = new FileInputStream(a)) {
                StreamUtils.copy(is, os);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        };
        // int c = 1 / 0; 出现异常会经过全局异常处理和ResponseBodyAdvice的实现类

        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=data.yml");
        headers.add(HttpHeaders.CONTENT_TYPE, "text/plain");

        ResponseEntity<StreamingResponseBody> response = new ResponseEntity<>(responseBody, headers, HttpStatus.OK);
        log.info("{}", response);
        return response;
    }

    @PostMapping("/excel")
    public ResponseEntity<StreamingResponseBody> exportExcel() {
        XSSFWorkbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("Sheet1");
        Row row = sheet.createRow(0);
        Cell cell = row.createCell(0);
        cell.setCellValue("Hello, World!");

        StreamingResponseBody responseBody = os -> {
            try {
                workbook.write(os);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        };

        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=data.xlsx");
        headers.add(HttpHeaders.CONTENT_TYPE, "application/x-download");
        return new ResponseEntity<>(responseBody, headers, HttpStatus.OK);
    }
}
